package middleware

import (
	"CMETO/models"
	"CMETO/utils/jwt"
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
)

func JWTAuth() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		auth := ctx.Request.Header.Get("Authorization")
		if len(auth) == 0 {
			// 没有token直接终止请求
			ctx.Abort()
			ctx.String(http.StatusOK, "未登录无权限")
			return
		}
		// 校验token，只要出错直接拒绝请求
		token, msg := jwt.ParseToken(auth)
		if token == nil {
			ctx.Abort()
			ctx.String(http.StatusOK, msg)
			return
		} else {
			// 控制器需要用到token的时候直接发送过去，随时取用
			ctx.Set("token", token)
		}
		ctx.Next()
	}
}

// 续签Token
// 普通令牌的时间不宜过长
// 生成一个过期时间较长的refresh_token
// 如果在refresh_token过期前10分钟请求会重新签发token返回给前端
func JWTAuthPlus() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		auth := ctx.Request.Header.Get("Authorization")
		if len(auth) == 0 {
			ctx.Abort()
			ctx.JSON(http.StatusOK, models.CheckResult{
				Msg:    "fail",
				Code:   "403",
				Result: jwt.OTHER,
			})
			return
		}
		// 校验token
		auth = strings.Split(auth, " ")[1]
		token, msg := jwt.ParseToken(auth)
		if msg != jwt.OK {
			if msg == jwt.EXP {
				// 判断是否过期，调用续签函数(判断逻辑在续签那里)
				newToken, _ := jwt.RenewToken(token)
				// 续签成功给响应头设置一个newtoken字段
				if newToken != "" {
					ctx.Header("newtoken", newToken)
					ctx.Request.Header.Set("Authorization", newToken)
					// 把新的解析给控制器
					lastetToken, _ := jwt.ParseToken(newToken)
					ctx.Set("token", lastetToken)
					ctx.Next()
					return
				}
			}
			// Token验证失败或续签失败直接拒绝请求
			ctx.Abort()
			ctx.JSON(http.StatusOK, models.CheckResult{
				Msg:    "fail",
				Code:   "403",
				Result: msg,
			})
			return
		}
		// token未过期继续执行其他中间件
		ctx.Set("token", token)
		ctx.Next()
	}
}
